package com.wei800.turnover.config.mybatis;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.IllegalSQLInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.wei800.turnover.config.mybatis.handler.YootkMetaObjectHandler;
import com.wei800.turnover.config.mybatis.handler.YootkTableNameHandler;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.io.IOException;

@Configuration
public class MyBatisPlusConfig { // MyBaits-Plus项目配置类
    @Bean
    public MybatisSqlSessionFactoryBean sqlSessionFactoryBean(
            DataSource dataSource,
            GlobalConfig globalConfig,
            MybatisPlusInterceptor mybatisPlusInterceptor) { // 注入全局配置实例
        MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
        factoryBean.setGlobalConfig(globalConfig); // 配置生效
        factoryBean.setDataSource(dataSource);
        factoryBean.setTypeHandlersPackage("com.wei800.turnover.config.mybatis.typehandler");
        factoryBean.setPlugins(new Interceptor[]{mybatisPlusInterceptor}); // 注入拦截器
        factoryBean.setTypeAliasesPackage("com.wei800.turnover.entity"); // 类型扫描包
                PathMatchingResourcePatternResolver resolver =
                new PathMatchingResourcePatternResolver(); // 路径匹配资源
        String mapperPath = PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                "META-INF/mybatis/mapper/*.xml"; // 所有Mapper文件的路径
        try {
            factoryBean.setMapperLocations(resolver.getResources(mapperPath));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return factoryBean;
    }
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
        configurer.setBasePackage("com.wei800.turnover.mapper");
        configurer.setAnnotationClass(Mapper.class);
        return configurer;
    }
    @Bean
    public GlobalConfig.DbConfig dbConfig() { // 全局数据配置
        GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
        // 如果此时你所有的逻辑删除字段是统一的名称，那么也可以直接在此定义
        dbConfig.setLogicDeleteField("status"); // 如果不统一，通过注解配置
        dbConfig.setLogicDeleteValue("1"); // 逻辑删除的内容
        dbConfig.setLogicNotDeleteValue("0"); // 逻辑未删除内容
        return dbConfig;
    }
    @Bean
    public GlobalConfig globalConfig(
            YootkMetaObjectHandler metaObjectHandler, // 数据填充器
            IdentifierGenerator generator,  // ID生成器
            ISqlInjector sqlInjector) { // SQL注入器
        GlobalConfig config = new GlobalConfig(); // 全局配置类
        config.setMetaObjectHandler(metaObjectHandler); // 填充器
        config.setIdentifierGenerator(generator); // 配置主键生成器
        config.setSqlInjector(sqlInjector); // 配置SQL注入器
//        config.setDbConfig(new GlobalConfig.DbConfig().setCapitalMode(false)); // 取消驼峰命名
        return config;
    }
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {    // MP拦截器
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor page = new PaginationInnerInterceptor(DbType.POSTGRE_SQL);
        // 如果数据返回量太高，首先不是正常的操作，其次内存会被严重占用，会导致OOM问题的
        page.setMaxLimit(500L); // 最多返回500数据
        interceptor.addInnerInterceptor(page); // 追加拦截器
        DynamicTableNameInnerInterceptor dynaTable = new DynamicTableNameInnerInterceptor();		// 动态表名称拦截器
        dynaTable.setTableNameHandler(new YootkTableNameHandler()); // 设置表名称转换器
        return interceptor;
    }
}
